<?php

namespace App\Admin\Controllers;

use App\Models\AlarmLevel;
use App\Models\AlarmMonitor;
use App\Http\Controllers\Controller;
use App\Models\Machine;
use App\Models\Productline;
use App\Models\Signalpoint;
use Encore\Admin\Controllers\HasResourceActions;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Show;

class AlarmMonitorController extends Controller
{
    use HasResourceActions;

    protected $header = '报警监控';

    /**
     * Index interface.
     *
     * @param Content $content
     * @return Content
     */
    public function index(Content $content)
    {
        $targetType = $this->getTargetType();
        return $content
            ->header(AlarmMonitor::$targetTypeNames[$targetType])
            ->description($this->header)
            ->body($this->grid($targetType));
    }

    /**
     * Show interface.
     *
     * @param mixed $id
     * @param Content $content
     * @return Content
     */
    public function show($id, Content $content)
    {
        return $content
            ->header('Detail')
            ->description('description')
            ->body($this->detail($id));
    }

    /**
     * Edit interface.
     *
     * @param mixed $id
     * @param Content $content
     * @return Content
     */
    public function edit($id, Content $content)
    {
        $productline = $this->getProductLine();
        return $content
            ->header($this->header)
            ->description(AlarmMonitor::$targetTypeNames[$this->getTargetType()])
            ->body($this->form($productline)->edit($id));
    }

    /**
     * Create interface.
     *
     * @param Content $content
     * @return Content
     */
    public function create(Content $content)
    {
        $productline = $this->getProductline();
        return $content
            ->header($this->header)
            ->description(AlarmMonitor::$targetTypeNames[$this->getTargetType()])
            ->body($this->form($productline));
    }

    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid($targetType)
    {
        $productline = $this->getProductline();
        $grid = new Grid(new AlarmMonitor);
        $grid->model()->where('targetType', $targetType)
            ->where('productlineId', $productline->id)
            ->with(['productline', 'level', 'target']);


        $grid->id('Id');
        $grid->pindex('指标名称')->display(function () {
            return $this->indexName;
        });
        $grid->column('level.name', '报警等级');
        $grid->monitorTime('时间范围')->display(function () {
            return $this->timeRangeName;
        });
        $grid->valueType('警位值类型')->display(function () {
            return $this->valueTypeName;
        });
        $grid->value('警位值')->display(function () {
            if ($this->valueType == AlarmMonitor::VALUE_TYPE_THRESHOLD) {
                return $this->threshold;
            } elseif ($this->valueType == AlarmMonitor::VALUE_TYPE_RANGE) {
                return sprintf('上限：%s<br/>下限：%s', $this->maximin, $this->minimum);
            } else {
                return '';
            }
        });
        $grid->alarmTip('描述');
        if ($targetType != AlarmMonitor::TARGET_TYPE_PRODUCT_LINE) {
            $grid->column('target.name', AlarmMonitor::$targetTypeNames[$targetType]);
        }

        $grid->column('productline.name', '生产线');

        $grid->filter(function ($filter) use ($targetType, $productline) {
            $filter->disableIdFilter();
            $productlines = Productline::all(['id', 'name']);
            $filter->equal('productlineId', '生产线')
                ->select($productlines->pluck('name', 'id'))
                ->default((string)$productlines->first()->id);
            if ($targetType == AlarmMonitor::TARGET_TYPE_MACHINE) {
                $filter->equal('targetId', AlarmMonitor::$targetTypeNames[AlarmMonitor::TARGET_TYPE_MACHINE])->select(Machine::inProductLine($productline->id)->pluck('name', 'id'));
            } elseif ($targetType == AlarmMonitor::TARGET_TYPE_SIGNAL_POINT) {
                $filter->equal('targetId', AlarmMonitor::$targetTypeNames[AlarmMonitor::TARGET_TYPE_SIGNAL_POINT])->select(Signalpoint::where('productlineId', $productline->id)->pluck('name', 'id'));
            }
        });
        $grid->expandFilter();
        $grid->disableCreateButton();
        $grid->disableExport();
        $grid->tools(function ($tools) use ($productline, $grid) {
            $tools->append(sprintf(
                '<div class="btn-group pull-right" style="margin-right: 10px"><a href="%s" class="btn btn-sm btn-success" title="新增"><i class="fa fa-save"></i><span class="hidden-xs">&nbsp;&nbsp;新增</span></a></div>',
                $grid->getCreateUrl() . '?productlineId=' . $productline->id
            ));
        });

        $grid->actions(function ($actions) use ($productline) {
            $actions->disableView();
            $actions->disableEdit();
            $actions->append(sprintf(
                '<a href="%s/%s/edit?productlineId=%s">&nbsp;&nbsp;编辑</a>',
                request()->getPathInfo(), $actions->getKey(), $productline->id
            ));
        });

        return $grid;
    }

    /**
     * Make a show builder.
     *
     * @param mixed $id
     * @return Show
     */
    protected function detail($id)
    {
        $show = new Show(AlarmMonitor::findOrFail($id));

        $show->id('Id');
        $show->productlineId('ProductlineId');
        $show->alarmTip('AlarmTip');
        $show->targetName('TargetName');
        $show->targetId('TargetId');
        $show->targetType('TargetType');
        $show->valueType('ValueType');
        $show->maximum('Maximum');
        $show->minimum('Minimum');
        $show->threshold('Threshold');
        $show->alarmLevelId('AlarmLevelId');
        $show->pindex('Index');
        $show->monitorTime('MonitorTime');

        return $show;
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form($productline = null)
    {
        $logPrefix = __METHOD__;
        $form = new Form(new AlarmMonitor);
        if (!$productline) {
            $productline = new Productline();
        }
        $targetType = $this->getTargetType();
        $form->html(sprintf('<h3>当前生产线：%s</h3>', $productline->name));
        $form->hidden('productlineId', '生产线')->value($productline->id);
        $form->hidden('targetType', '目标类型')->value($targetType);
        if ($targetType == AlarmMonitor::TARGET_TYPE_PRODUCT_LINE) {
            $form->hidden('targetId')->value($productline->id);
            $indexes = AlarmMonitor::indexOfProductLine();
            $form->radio('pindex', '报警指标')->options($indexes)->default(array_first(array_keys($indexes)))->rules('required');
        } elseif ($targetType == AlarmMonitor::TARGET_TYPE_MACHINE) {
            $form->select('targetId', '机台')->options(Machine::inProductLine($productline->id)->pluck('name', 'id'))->rules('required');
            $indexes = AlarmMonitor::indexOfMachine();
            $form->radio('pindex', '报警指标')->options($indexes)->default(array_first(array_keys($indexes)))->rules('required');
        } elseif ($targetType == AlarmMonitor::TARGET_TYPE_SIGNAL_POINT) {
            $form->select('targetId', '点位')->options(Signalpoint::selectOptions($productline->id))->rules('required');
        }

        $form->radio('monitorTime', '时间范围')->options(AlarmMonitor::$timeRangeNames)->default(AlarmMonitor::TIME_RANGE_REAL_TIME)->rules('required');

        $alarmLevels = AlarmLevel::all(['id', 'name']);
        $form->radio('alarmLevelId', '报警等级')->options($alarmLevels->pluck('name', 'id'))->default($alarmLevels->first()->id)->rules('required');
        $form->radio('valueType', '值类型')->options(AlarmMonitor::$valueTypeNames)->default(AlarmMonitor::VALUE_TYPE_THRESHOLD)->rules('required');
        $form->text('threshold', '阀值')->help('值类型为' . AlarmMonitor::$valueTypeNames[AlarmMonitor::VALUE_TYPE_THRESHOLD] . '时必须')->rules("numeric|required_if:valueType," . AlarmMonitor::VALUE_TYPE_THRESHOLD);
        $form->text('maximum', '上限')->help('值类型为' . AlarmMonitor::$valueTypeNames[AlarmMonitor::VALUE_TYPE_RANGE] . '时必须')->rules("numeric|required_if:valueType," . AlarmMonitor::VALUE_TYPE_RANGE);
        $form->text('minimum', '下限')->help('值类型为' . AlarmMonitor::$valueTypeNames[AlarmMonitor::VALUE_TYPE_RANGE] . '时必须')->rules("numeric|required_if:valueType," . AlarmMonitor::VALUE_TYPE_RANGE);
        $form->textarea('alarmTip', '描述');

        $form->tools(function ($tools) use ($productline) {
            $tools->disableView();
            $tools->disableList();
            if (request()->is('*create*')) {
                $baseUrl = $this->resource(-1);
                $tools->disableDelete();
            } else {
                $baseUrl = $this->resource(-2);
            }
            $tools->append(sprintf(
                '<div class="btn-group pull-right" style="margin-right: 5px"><a href="%s?productlineId=%s" class="btn btn-sm btn-default" title="列表"><i class="fa fa-list"></i><span class="hidden-xs">&nbsp;列表</span></a></div>',
                $baseUrl, $productline->id
            ));
        });

        $form->saved(function ($form) use ($logPrefix, $productline) {
            $model = $form->model();
            $target = $model->target;
            $model->update(['targetName' => $target->name]);
            if (request()->isMethod('POST')) {
                $baseUrl = $form->resource(0);
            } else {
                $baseUrl = $form->resource(-1);
            }
            return redirect($baseUrl . '?productlineId=' . $productline->id);
        });

        return $form;
    }

    private function getTargetType()
    {
        $request = request();
        if ($request->is('*productline*')) {
            return AlarmMonitor::TARGET_TYPE_PRODUCT_LINE;
        } elseif ($request->is('*machine*')) {
            return AlarmMonitor::TARGET_TYPE_MACHINE;
        } elseif ($request->is('*signal-point*')) {
            return AlarmMonitor::TARGET_TYPE_SIGNAL_POINT;
        } else {
            return abort(404);
        }
    }

}
